package com.horoscope.astrology.zodiac.signs.free.utils;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.ImageView;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

import java.util.concurrent.TimeUnit;

// https://blog.csdn.net/ci250454344/article/details/82800520
public class AnimationManager {

    private static AnimationManager sAnimationManager;
//    private Handler mHandler = new Handler(Looper.getMainLooper());
    private long fps;
    private int[] res;
    private int oneImage;
    private int count = 1;
    private int length = 0;
    private ImageView intoView;
    private Bitmap nextBitmap;
    private Bitmap currentBitmap;
    private Disposable mSubscribe;
    private Disposable mDisposable;

    private AnimationManager() {
    }

    public Disposable getSubscribe() {
        return mSubscribe;
    }

    public Disposable getmDisposable() {
        return mDisposable;
    }

    public static AnimationManager getInstance() {
        if (sAnimationManager == null) {
            sAnimationManager = new AnimationManager();
        }
        return sAnimationManager;
    }

    AnimationManager initDrawableList(long fps, int... Res) {
        this.fps = fps;
        this.res = Res;
        count = 1;
        if (Res.length == 0) {
            throw new RuntimeException("不能是空数组");
        }
        this.oneImage = Res[0];
        length = Res.length;
        return this;
    }

    public AnimationManager into(ImageView view) {
        this.intoView = view;
        // 加载第一张
        mDisposable = Observable.just(oneImage)
                .observeOn(Schedulers.io())
                .map(new Function<Integer, Bitmap>() { // 将上游的数据格式转成我们需要的数据格式 Integer -> Bitmap
                    @Override
                    public Bitmap apply(Integer integer) {
                        BitmapFactory.Options opts = getOptions(integer);
                        // 加载下一张
                        if (res.length > 1) {
                            nextBitmap = BitmapFactory.decodeResource(intoView.getResources(), res[count++], opts);
                        }
                        return BitmapFactory.decodeResource(intoView.getResources(), integer, opts);
                    }
                })
                .onErrorReturn(new Function<Throwable, Bitmap>() {
                    @Override
                    public Bitmap apply(Throwable throwable) {
                        return null;
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Bitmap>() {
                    @Override
                    public void accept(Bitmap bitmap) {
                        intoView.setImageBitmap(bitmap);
                    }
                });
        return this;
    }

    @NonNull
    private BitmapFactory.Options getOptions(Integer integer) {
        // 先获取图片的和IamgeView各自的宽高
        BitmapFactory.Options opts = new BitmapFactory.Options();
        //给opts配置只获取图片的元数据
        opts.inJustDecodeBounds = true;
        //注意：由于配置了opts并且是仅仅获取图片边界的属性，因此该方法返回的对象永远为null
        BitmapFactory.decodeResource(intoView.getResources(), integer, opts);
        //从opts对象上获取图片的宽高
        int width = opts.outWidth;
        int height = opts.outHeight;

        int width1 = SysUtils.getScreenWidthPixels(intoView.getContext());
        int height1 = SysUtils.getScreenHeightPixels(intoView.getContext());

        int sampleSize = Math.max(width / width1, height / height1);


        opts.inJustDecodeBounds = false;//必须配置为加载图片，而不是仅仅获取图片的尺寸
        opts.inSampleSize = sampleSize; //配置等比例缩放的倍数
        return opts;
    }

    public synchronized void start() {
        mSubscribe = Observable.interval(fps, TimeUnit.MILLISECONDS)
                .observeOn(Schedulers.io())
                .map(new Function<Long, Boolean>() { // 将上游的数据格式转成我们需要的数据格式 Long -> Boolean
                    @Override
                    public Boolean apply(Long aLong) {
                        count++;
                        if (nextBitmap != null) {
                            currentBitmap = nextBitmap;
                        }
                        if (count > res.length - 1) {
                            return false;
                        }
                        BitmapFactory.Options opts = getOptions(res[count]);
                        nextBitmap = BitmapFactory.decodeResource(intoView.getResources(), res[count], opts);
                        return true;
                    }
                }).onErrorReturn(new Function<Throwable, Boolean>() {
                    @Override
                    public Boolean apply(Throwable throwable) throws Exception {
                        return false;
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Boolean>() {
                    @Override
                    public void accept(Boolean flag) {
                        if (flag) {
                            intoView.setImageBitmap(currentBitmap);
                        } else {
                            mSubscribe.dispose();
                        }

                    }
                });
    }
}